home *** CD-ROM | disk | FTP | other *** search
/ AmigActive 26 / AACD 26.iso / AACD / Programming / ace_gpl_release / src_ansi / ace / c / sub.c < prev    next >
Encoding:
C/C++ Source or Header  |  1999-01-05  |  9.3 KB  |  395 lines

  1. /* << ACE >>
  2.  
  3.    -- Amiga BASIC Compiler --
  4.  
  5.    ** Parser: subprogram code **
  6.    ** Copyright (C) 1998 David Benn
  7.    ** 
  8.    ** This program is free software; you can redistribute it and/or
  9.    ** modify it under the terms of the GNU General Public License
  10.    ** as published by the Free Software Foundation; either version 2
  11.    ** of the License, or (at your option) any later version.
  12.    **
  13.    ** This program is distributed in the hope that it will be useful,
  14.    ** but WITHOUT ANY WARRANTY; without even the implied warranty of
  15.    ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  16.    ** GNU General Public License for more details.
  17.    **
  18.    ** You should have received a copy of the GNU General Public License
  19.    ** along with this program; if not, write to the Free Software
  20.    ** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
  21.  
  22.    Author: David J Benn
  23.    Date: 26th October-30th November, 1st-13th December 1991,
  24.    14th,20th-27th January 1992, 
  25.    2nd-17th, 21st-29th February 1992, 
  26.    1st,13th,14th,22nd,23rd March 1992,
  27.    21st,22nd April 1992,
  28.    2nd,3rd,11th,15th,16th May 1992,
  29.    7th,8th,9th,11th,13th,14th,28th,29th,30th June 1992,
  30.    2nd-8th,14th-19th,26th-29th July 1992,
  31.    1st-3rd,7th,8th,9th August 1992,
  32.    6th,7th December 1992,
  33.    24th March 1993,
  34.    14th,20th,30th June 1993,
  35.    18th December 1993,
  36.    12th,21st June 1994
  37.  */
  38.  
  39. #include "acedef.h"
  40. #include <string.h>
  41.  
  42. /* locals */
  43. static char *frame_ptr[] = {"(a4)", "(a5)"};
  44.  
  45. /* externals */
  46. extern int sym;
  47. extern int typ;
  48. extern int lev;
  49. extern char id[MAXIDSIZE];
  50. extern SYM *curr_item;
  51. extern CODE *curr_code;
  52. extern int addr[2];
  53.  
  54. /* functions */
  55. void forward_ref (void)
  56. {
  57.   char sub_name[80];
  58.   SYM *sub_ptr;
  59.   short param_count = 0;
  60.   int param_type;
  61.   int sub_type = undefined;
  62. /* declare a forward reference to a SUB -- see declare() 
  63.    NO checking against symbol table is carried out */
  64.  
  65.   insymbol ();
  66.  
  67.   /* type identifiers */
  68.   if (sym == shortintsym || sym == longintsym || sym == addresssym ||
  69.       sym == singlesym || sym == stringsym)
  70.     {
  71.       switch (sym)
  72.     {
  73.     case shortintsym:
  74.       sub_type = shorttype;
  75.       break;
  76.     case longintsym:
  77.       sub_type = longtype;
  78.       break;
  79.     case addresssym:
  80.       sub_type = longtype;
  81.       break;
  82.     case singlesym:
  83.       sub_type = singletype;
  84.       break;
  85.     case stringsym:
  86.       sub_type = stringtype;
  87.       break;
  88.     }
  89.       insymbol ();
  90.     }
  91.  
  92.   if (sym != ident)
  93.     _error (7);
  94.   else
  95.     {
  96.       /* get the name */
  97.       strcpy (sub_name, "_SUB_");
  98.       strcat (sub_name, id);
  99.  
  100.       /* enter it into symbol table & mark as forward ref. */
  101.       if (!exist (sub_name, subprogram))
  102.     {
  103.       if (sub_type == undefined)
  104.         sub_type = typ;
  105.       enter (sub_name, sub_type, subprogram, 0);
  106.       curr_item->decl = fwdref;
  107.     }
  108.       else
  109.     _error (33);        /* subprogram already declared */
  110.  
  111.       sub_ptr = curr_item;
  112.  
  113.       /* get parameters -- if any */
  114.       insymbol ();
  115.       if (sym != lparen)
  116.     {
  117.       /* Is this an external subprogram? */
  118.       if (sym == externalsym)
  119.         {
  120.           insymbol ();
  121.           enter_XREF (sub_name);
  122.           sub_ptr->address = extfunc;
  123.         }
  124.  
  125.       sub_ptr->no_of_params = 0;
  126.       return;        /* no parameters -> return sym */
  127.     }
  128.       else
  129.     {
  130.       /* parameters expected */
  131.       do
  132.         {
  133.           param_type = undefined;
  134.  
  135.           insymbol ();
  136.  
  137.           /* type identifiers */
  138.           if (sym == shortintsym || sym == longintsym || sym == addresssym ||
  139.           sym == singlesym || sym == stringsym)
  140.         {
  141.           switch (sym)
  142.             {
  143.             case shortintsym:
  144.               param_type = shorttype;
  145.               break;
  146.             case longintsym:
  147.               param_type = longtype;
  148.               break;
  149.             case addresssym:
  150.               param_type = longtype;
  151.               break;
  152.             case singlesym:
  153.               param_type = singletype;
  154.               break;
  155.             case stringsym:
  156.               param_type = stringtype;
  157.               break;
  158.             }
  159.           insymbol ();
  160.         }
  161.  
  162.           if (sym != ident)
  163.         _error (7);    /* ident expected */
  164.           else
  165.         {
  166.           /* store parameter type */
  167.           if (param_type == undefined)
  168.             param_type = typ;
  169.           sub_ptr->p_type[param_count] = param_type;
  170.           param_count++;
  171.         }
  172.           insymbol ();
  173.         }
  174.       while ((sym == comma) && (param_count < MAXPARAMS));
  175.  
  176.       sub_ptr->no_of_params = param_count;
  177.  
  178.       if (param_count == MAXPARAMS)
  179.         _error (42);    /* too many */
  180.  
  181.       if (sym != rparen)
  182.         _error (9);
  183.       insymbol ();
  184.  
  185.       /* Is this an external subprogram? */
  186.       if (sym == externalsym)
  187.         {
  188.           insymbol ();
  189.           enter_XREF (sub_name);
  190.           sub_ptr->address = extfunc;
  191.         }
  192.     }
  193.     }
  194. }
  195.  
  196.  
  197. void sub_params (SYM * sub_ptr)
  198. {
  199.   SHORT param_count = 0;
  200.   int param_type;
  201.   char addrbuf[40];
  202.  
  203.   /* parse current SUB's formal parameter list */
  204.  
  205.   insymbol ();
  206.   if (sym != lparen)
  207.     {
  208.       sub_ptr->no_of_params = 0;
  209.       return;            /* no parameters -> return sym */
  210.     }
  211.   else
  212.     {
  213.       /* if actual parameters passed, Forbid() called -> Permit() */
  214.       gen ("movea.l", "_AbsExecBase", "a6");
  215.       gen ("jsr", "_LVOPermit(a6)", "  ");
  216.       enter_XREF ("_AbsExecBase");
  217.       enter_XREF ("_LVOPermit");
  218.  
  219.       /* formal parameters expected */
  220.       do
  221.     {
  222.       param_type = undefined;
  223.  
  224.       insymbol ();
  225.  
  226.       /* type identifiers */
  227.       if (sym == shortintsym || sym == longintsym || sym == addresssym ||
  228.           sym == singlesym || sym == stringsym)
  229.         {
  230.           switch (sym)
  231.         {
  232.         case shortintsym:
  233.           param_type = shorttype;
  234.           break;
  235.         case longintsym:
  236.           param_type = longtype;
  237.           break;
  238.         case addresssym:
  239.           param_type = longtype;
  240.           break;
  241.         case singlesym:
  242.           param_type = singletype;
  243.           break;
  244.         case stringsym:
  245.           param_type = stringtype;
  246.           break;
  247.         }
  248.           insymbol ();
  249.         }
  250.  
  251.       if (sym != ident)
  252.         _error (7);        /* ident expected */
  253.       else
  254.         {
  255.           if (!exist (id, variable))    /* treat param's as local variables */
  256.         {
  257.           /* if type not already specified, take type indicated by ident */
  258.           if (param_type == undefined)
  259.             param_type = typ;
  260.  
  261.           /* enter parameter as a variable into symbol table */
  262.           enter (id, param_type, variable, 0);
  263.  
  264.           /* string parameter? -> associate with BSS object */
  265.           if (curr_item->type == stringtype)
  266.             {
  267.               itoa (-1 * curr_item->address, addrbuf, 10);
  268.               strcat (addrbuf, frame_ptr[ONE]);
  269.               gen ("move.l", addrbuf, "-(sp)");        /* push value parameter */
  270.               assign_to_string_variable (curr_item, MAXSTRLEN);
  271.             }
  272.         }
  273.           else
  274.         _error (38);    /* duplicate parameter */
  275.         }
  276.  
  277.       /* store parameter type */
  278.       sub_ptr->p_type[param_count] = param_type;
  279.       param_count++;
  280.  
  281.       insymbol ();
  282.     }
  283.       while ((sym == comma) && (param_count < MAXPARAMS));
  284.  
  285.       sub_ptr->no_of_params = param_count;
  286.  
  287.       if (param_count == MAXPARAMS)
  288.     _error (42);        /* too many */
  289.  
  290.       if (sym != rparen)
  291.     _error (9);
  292.       insymbol ();
  293.     }
  294. }
  295.  
  296. void parse_shared_vars (void)
  297. {
  298.   SYM *zero_ptr, *one_ptr;
  299.   int i;
  300.   char buf0[40], buf1[40], num[40];
  301.   BOOL share_it;
  302.  
  303.   /* get the SHARED list for current SUB and store details */
  304.  
  305.   do
  306.     {
  307.       share_it = FALSE;
  308.       insymbol ();
  309.       if (sym != ident)
  310.     _error (7);        /* identifier expected */
  311.       else
  312.     {
  313.       lev = ZERO;
  314.       if (exist (id, variable) || exist (id, structure))
  315.         {
  316.           share_it = TRUE;
  317.           zero_ptr = curr_item;
  318.           lev = ONE;
  319.           enter (id, zero_ptr->type, zero_ptr->object, 0);    /* variable or structure */
  320.           one_ptr = curr_item;
  321.           /* add another 2 bytes to address if short */
  322.           if (one_ptr->type == shorttype)
  323.         {
  324.           addr[lev] += 2;
  325.           one_ptr->address = addr[lev];
  326.         }
  327.           zero_ptr->shared = TRUE;
  328.           one_ptr->shared = TRUE;
  329.           if (one_ptr->type == stringtype)
  330.         one_ptr->new_string_var = FALSE;    /* don't want a new BSS object! */
  331.           if (one_ptr->object == structure)
  332.         one_ptr->other = zero_ptr->other;    /* pointer to structdef SYM node */
  333.         }
  334.       else if (exist (id, array))
  335.         {
  336.           share_it = TRUE;
  337.           zero_ptr = curr_item;
  338.           lev = ONE;
  339.           enter (id, zero_ptr->type, array, zero_ptr->dims);
  340.           one_ptr = curr_item;
  341.           zero_ptr->shared = TRUE;
  342.           one_ptr->shared = TRUE;
  343.           /* copy array index values from level ZERO to ONE */
  344.           for (i = 0; i <= zero_ptr->dims; i++)
  345.         one_ptr->index[i] = zero_ptr->index[i];
  346.           /* get string array element size? */
  347.           if (one_ptr->type == stringtype)
  348.         one_ptr->numconst.longnum = zero_ptr->numconst.longnum;
  349.         }
  350.       else
  351.         {
  352.           _error (40);
  353.           lev = ONE;
  354.         }
  355.  
  356.       if (share_it)
  357.         {
  358.           /* copy size information for SIZEOF? */
  359.           if (one_ptr->type == stringtype ||
  360.           one_ptr->object == array ||
  361.           one_ptr->object == structure)
  362.         one_ptr->size = zero_ptr->size;
  363.  
  364.           /* copy address of object from level ZERO to level ONE stack frame */
  365.  
  366.           /* frame location of level ONE object */
  367.           itoa (-1 * one_ptr->address, buf1, 10);
  368.           strcat (buf1, "(a5)");
  369.  
  370.           /* if simple numeric variable (short,long,single) or structure 
  371.              -> get address */
  372.           if ((zero_ptr->type != stringtype) && (zero_ptr->object != array))
  373.         {
  374.           strcpy (num, "#\0");
  375.           itoa (zero_ptr->address, buf0, 10);
  376.           strcat (num, buf0);
  377.           gen ("move.l", "a4", "d0");    /* frame pointer */
  378.           gen ("sub.l", num, "d0");    /* offset from frame top */
  379.           gen ("move.l", "d0", buf1);    /* store address in level ONE frame */
  380.         }
  381.           else
  382.         {
  383.           /* array or string -> level ZERO already contains address */
  384.           itoa (-1 * zero_ptr->address, buf0, 10);
  385.           strcat (buf0, "(a4)");
  386.           gen ("move.l", buf0, buf1);
  387.         }
  388.         }
  389.     }
  390.  
  391.       insymbol ();
  392.     }
  393.   while (sym == comma);
  394. }
  395.